import { getAsyncRoutes } from '@/api/routes'
import type { RouteRecordRaw } from 'vue-router'
import { usePermissionStore } from '@/stores/modules/permission'
import LAYOUT from '@/layout/index.vue'
import router from './index'
import { deepCopy, isString } from '@/utils'
import { useUserStore } from '@/stores/modules/user'
const modulesRoutes = import.meta.glob('/src/views/**/*.{vue,tsx}')
export const getAuthCode = (): Array<string> => {
  return (router.currentRoute.value.meta?.auths as Array<string>) || []
}
/**
 * @description 是否有按钮级别的权限（根据路由`meta`中的`auths`字段进行判断）
 */
function containsAllElements(mother: any[], child: any[]): boolean {
  const motherSet = new Set(mother)
  for (const element of child) {
    if (!motherSet.has(element)) {
      return false
    }
  }
  return true
}
export const hasAuth = (value: string | string[]) => {
  if (!value) return false
  const auths = getAuthCode()
  return isString(value) ? auths.includes(value) : containsAllElements(auths, value)
}
export const flattenTree = (tree: RouteRecordRaw[]): RouteRecordRaw[] => {
  return tree.reduce((acc, node) => {
    acc.push(node)
    if (node.children) {
      acc.push(...flattenTree(node.children))
    }
    return acc
  }, [] as RouteRecordRaw[])
}

/** 按照路由中meta下的sort等级升序来排序路由 */
export const sortAsyncRoutes = (routes: any[]) => {
  return routes.sort((a, b) => {
    return ((a.meta?.sort as number) || 0) - ((b.meta?.sort as number) || 0)
  })
}
/** 过滤meta中showLink为false的菜单 */
export const filterTree = (data: RouteRecordRaw[]) => {
  return deepCopy(data).filter((item) => {
    if (item.meta?.showLink === false) return false
    if (item.children) item.children = filterTree(item.children)
    return true
  })
}
function addPathMatch() {
  if (!router.hasRoute('pathMatch')) {
    router.addRoute({
      path: '/:pathMatch(.*)',
      name: 'pathMatch',
      redirect: '/error/404'
    })
  }
}
const addAsyncRoutes = (arrRoutes: RouteRecordRaw[]) => {
  if (!arrRoutes?.length) return
  const modulesRoutesKeys = Object.keys(modulesRoutes)
  arrRoutes.forEach((route) => {
    // 将backstage属性加入meta，标识此路由为后端返回路由
    if (route.meta?.backstage) {
      route.meta.backstage = true
    }
    // 如果子级存在且父级的redirect属性不存在，默认取第一个子级的path
    if (route?.children?.length && !route.redirect) {
      route.redirect = route.children[0].path
    }
    if (route?.children?.length && !route.redirect) route.redirect = route.children[0].path
    if (route?.children?.length && !route.name)
      route.name = (route.children[0].name as string) + 'Parent'
    if (route?.component && (route.component as any) === 'LAYOUT') {
      route.component = LAYOUT
    } else {
      const index = route?.component
        ? modulesRoutesKeys.findIndex((ev) => ev.includes(route.component as any))
        : modulesRoutesKeys.findIndex((ev) => ev.includes(route.path))
      const component = modulesRoutes[modulesRoutesKeys[index]]
      if (component) {
        route.component = component
      } else {
        arrRoutes.splice(index, 1)
      }
    }
    if (route?.children?.length) {
      addAsyncRoutes(route.children)
    }
  })
  return arrRoutes
}
const handleAsyncRoutes = (routeList: RouteRecordRaw[]) => {
  if (routeList.length === 0) {
    usePermissionStore().handleWholeMenus(routeList)
  } else {
    console.log(
      '%c [ routeList ]-101',
      'font-size:13px; background:pink; color:#bf2c9f;',
      routeList
    )

    const routeLists = addAsyncRoutes(routeList) || []
    const flattenRouters: any = router.getRoutes().find((n) => n.path === '/')
    if (flattenRouters) {
      routeLists.forEach((v: RouteRecordRaw) => {
        if (!router.hasRoute(v?.name as string)) {
          router.addRoute(flattenRouters.name, v)
        }
      })
    }
    usePermissionStore().handleWholeMenus(routeList)
  }
  addPathMatch()
}

/** 获取所有菜单中的第一个菜单（顶级菜单）*/
export function getTopMenu() {
  return usePermissionStore().wholeMenus[0]
}
export const initRouter = () => {
  const userStore = useUserStore()
  return new Promise((resolve) => {
    getAsyncRoutes().then(async (res: any) => {
      handleAsyncRoutes(res)
      await userStore.setUserInfo()
      resolve(res)
    })
  })
}
